package com.yhos.platform.oopston.service.biz.sensitiveword;

import com.yhos.platform.oopston.base.utils.TypeConverter;
import com.yhos.platform.oopston.mapper.mapper.SensitiveWordMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @Description: 敏感词过滤
 */
@Component
public class SensitiveWordFilter {

    @Autowired
    private SensitiveWordMapper sensitiveWordWapper;
    @SuppressWarnings("rawtypes")
    private static Map sensitiveWordMap = null;
    private static Map sensitiveLevelMap = null;
    public static int minMatchTYpe = 1; // 最小匹配规则
    public static int maxMatchType = 2; // 最大匹配规则

    /**
     * 构造函数，初始化敏感词库
     */
    @Autowired
    public SensitiveWordFilter(SensitiveWordMapper sensitiveWordWapper) {
        this.sensitiveWordWapper = sensitiveWordWapper;

        reloadSensitiveWordMap();
    }

    public void reloadSensitiveWordMap() {
        List<Map> rowList = this.sensitiveWordWapper.findAllSensitiveWord();
        sensitiveWordMap = SensitiveWordInit.buildSensitiveWordMap(rowList);
//		sensitiveLevelMap = SensitiveWordInit.buildSensitiveLevelMap(rowList);
    }


    public Map<String, Set<String>> getSensitiveWordAndLevelMap(Map<String, String> valueHashMap) {
        if (valueHashMap == null || valueHashMap.size() == 0) {
            return null;
        }

        Map<String, Set<String>> sensitiveWords = new HashMap();

        Set<String> keySet = valueHashMap.keySet();
        Iterator itor = keySet.iterator();
        while (itor.hasNext()) {
            String key = (String) itor.next();
            String content = (String) valueHashMap.get(key);
            if (content == null)
                continue;
            Set<String> wordAndLevels = getSensitiveWordAndLevel(content, SensitiveWordFilter.minMatchTYpe);
            if (wordAndLevels != null && wordAndLevels.size() > 0) {
                sensitiveWords.put(key, wordAndLevels);
            }
        }
        return sensitiveWords;
    }

    public Set<String> getSensitiveWord(Map<String, String> valueHashMap) {
        if (valueHashMap == null || valueHashMap.size() == 0) {
            return null;
        }

        Set<String> sensitiveWords = new HashSet();
        String[] strArray = TypeConverter.toArray(TypeConverter.join(valueHashMap.values(), ",", "", "").toString());
        if (strArray != null && strArray.length > 0) {
            for (int i = 0; i < strArray.length; i++) {
                String content = strArray[i];
                Set<String> words = getSensitiveWord(content, SensitiveWordFilter.minMatchTYpe);
                if (words != null && words.size() > 0) {
                    sensitiveWords.addAll(words);
                }
            }
        }
        return sensitiveWords;
    }

    /**
     * 获取文字中的敏感词
     *
     * @param txt       文字
     * @param matchType 匹配规则&nbsp;1：最小匹配规则，2：最大匹配规则
     * @return
     * @version 1.0
     */
    public Set<String> getSensitiveWord(String txt, int matchType) {
        Set<String> sensitiveWordList = new HashSet<String>();

        for (int i = 0; i < txt.length(); i++) {
            int length = checkSensitiveWord(txt, i, matchType); // 判断是否包含敏感字符
            if (length > 0) { // 存在,加入list中
                sensitiveWordList.add(txt.substring(i, i + length));
                i = i + length - 1; // 减1的原因，是因为for会自增
            }
        }

        return sensitiveWordList;
    }

    /**
     * 获取文字中的敏感词（包括级别属性）
     *
     * @param txt       文字
     * @param matchType 匹配规则&nbsp;1：最小匹配规则，2：最大匹配规则
     * @return
     * @version 1.0
     */
    public Set<String> getSensitiveWordAndLevel(String txt, int matchType) {
        Set<String> sensitiveWordList = new HashSet<String>();

        for (int i = 0; i < txt.length(); i++) {
            int length = checkSensitiveWord(txt, i, matchType); // 判断是否包含敏感字符
            if (length > 0) { // 存在,加入list中
                String word = txt.substring(i, i + length);
                String level = TypeConverter.toString(sensitiveLevelMap.get(word));
                String wordAndLevle = word;
                sensitiveWordList.add(wordAndLevle);
                i = i + length - 1; // 减1的原因，是因为for会自增
            }
        }

        return sensitiveWordList;
    }

    public boolean containSensitiveWord(List<String> contentList) {
        if (contentList == null || contentList.size() == 0) {
            return false;
        }
        String[] strArray = TypeConverter.toArray(TypeConverter.join(contentList, ",", "", "").toString());
        boolean isSensitive = false;
        if (strArray != null && strArray.length > 0) {
            for (int i = 0; i < strArray.length; i++) {
                String content = strArray[i];
                if (containSensitiveWord(content, 1)) {
                    isSensitive = true;
                    break;
                }
            }
        }
        return isSensitive;
    }

    /**
     * 判断文字是否包含敏感字符
     *
     * @param txt       文字
     * @param matchType 匹配规则&nbsp;1：最小匹配规则，2：最大匹配规则
     * @return 若包含返回true，否则返回false
     * @version 1.0
     */
    public boolean containSensitiveWord(String txt, int matchType) {
        if (txt == null || txt.length() == 0) {
            return false;
        }
        boolean flag = false;
        for (int i = 0; i < txt.length(); i++) {
            int matchFlag = this.checkSensitiveWord(txt, i, matchType); // 判断是否包含敏感字符
            if (matchFlag > 0) { // 大于0存在，返回true
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 检查文字中是否包含敏感字符，检查规则如下：<br>
     *
     * @param txt
     * @param beginIndex
     * @param matchType
     * @return，如果存在，则返回敏感词字符的长度，不存在返回0
     * @version 1.0
     */
    @SuppressWarnings({"rawtypes"})
    public int checkSensitiveWord(String txt, int beginIndex, int matchType) {
        boolean isEnd = false; // 敏感词结束标识位
        int matchWordCount = 0; // 匹配标识数默认为0
        char word = 0;
        Map nowMap = sensitiveWordMap;
        for (int i = beginIndex; i < txt.length(); i++) {
            word = txt.charAt(i);
            nowMap = (Map) nowMap.get(word); // 获取指定key
            if (nowMap != null) { // 存在，则判断是否为最后一个
                matchWordCount++; // 找到相应key，匹配标识+1
                if ("1".equals(nowMap.get("isEnd"))) { // 如果为最后一个匹配规则,结束循环，返回匹配标识数
                    isEnd = true; // 结束标志位为true
                    if (SensitiveWordFilter.minMatchTYpe == matchType) { // 最小规则，直接返回,最大规则还需继续查找
                        break;
                    }
                }
            } else { // 不存在，直接返回
                break;
            }
        }
        //if (matchFlag < 2 || !isEnd) {
        if (matchWordCount >= 1 && isEnd) { // 匹配到的词的长度大于等于1，且有结束标志
        } else {
            matchWordCount = 0;
        }
        return matchWordCount;
    }

    /**
     * 替换敏感字字符
     *
     * @param txt
     * @param matchType
     * @param replaceChar 替换字符，默认*
     * @version 1.0
     */
    public String replaceSensitiveWord(String txt, int matchType,
                                       String replaceChar) {
        String resultTxt = txt.toLowerCase();
        Set<String> set = getSensitiveWord(txt.toLowerCase(), matchType); // 获取所有的敏感词
        Iterator<String> iterator = set.iterator();
        String word = null;
        String replaceString = null;
        while (iterator.hasNext()) {
            word = iterator.next();
            replaceString = getReplaceChars(replaceChar, word.length());
            resultTxt = resultTxt.replaceAll(word, replaceString);
        }

        return resultTxt;
    }

    /**
     * 获取替换字符串
     *
     * @param replaceChar
     * @param length
     * @return
     * @version 1.0
     */
    private String getReplaceChars(String replaceChar, int length) {
        String resultReplace = replaceChar;
        for (int i = 1; i < length; i++) {
            resultReplace += replaceChar;
        }

        return resultReplace;
    }
}
